package top.jiangqiang.qianyi.common.auth.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.crypto.SecureUtil;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.NullMarked;
import top.jiangqiang.qianyi.common.auth.TokenPlayLoad;
import top.jiangqiang.qianyi.common.cache.CacheService;
import top.jiangqiang.qianyi.common.constants.auth.Platform;
import top.jiangqiang.qianyi.common.id.IdUtil;
import top.jiangqiang.qianyi.common.properties.AuthProperties;

import static top.jiangqiang.qianyi.common.constants.GlobalConstants.CacheConstants.TOKEN_PREFIX;
import static top.jiangqiang.qianyi.common.constants.GlobalConstants.CacheConstants.USER_LOGOUT_TIME_PREFIX;

@RequiredArgsConstructor
@Slf4j
@NullMarked
public class DefaultAuthServiceImpl implements AuthService {
    private final AuthProperties authProperties;
    private final CacheService cacheService;


    @Override
    public String login(Long userId, Platform platform) {
        TokenPlayLoad playLoad = new TokenPlayLoad(userId, platform);
        String token = SecureUtil.sha256(playLoad.getUserId() + playLoad.getPlatform().name() + playLoad.getLoginTime()) + IdUtil.nextUUID();
        cacheService.put(TOKEN_PREFIX + token, playLoad, authProperties.getDuration());
        return token;
    }

    @Override
    public void logout(Long userId) {
        cacheService.put(USER_LOGOUT_TIME_PREFIX + userId, System.currentTimeMillis(), authProperties.getDuration());
    }

    @Override
    public void logout(Long userId, Platform platform) {
        cacheService.put(USER_LOGOUT_TIME_PREFIX + userId + ":" + platform, System.currentTimeMillis(), authProperties.getDuration());
    }

    @Override
    @Nullable
    public TokenPlayLoad validate(String token) {
        if (StrUtil.isBlank(token)) {
            return null;
        }
        TokenPlayLoad playLoad = cacheService.get(TOKEN_PREFIX + token);
        if (playLoad == null) {
            return null;
        }
        //全局退出时间
        Long globalLogoutTime = cacheService.get(USER_LOGOUT_TIME_PREFIX + playLoad.getUserId());
        if (globalLogoutTime != null && playLoad.getLoginTime() <= globalLogoutTime) {
            cacheService.remove(TOKEN_PREFIX + token);
            //判断全局多端退出标志
            return null;
        }
        //指定平台端退出时间
        Long logoutTime = cacheService.get(USER_LOGOUT_TIME_PREFIX + playLoad.getUserId() + ":" + playLoad.getPlatform());
        if (logoutTime != null && playLoad.getLoginTime() <= logoutTime) {
            cacheService.remove(TOKEN_PREFIX + token);
            return null;
        }
        renewTtl(token);
        return playLoad;
    }

    @Override
    public boolean renewTtl(String token) {
        //刷新当前token时间
        return cacheService.renewTtl(TOKEN_PREFIX + token, authProperties.getDuration());
    }

}
